package com.fyzk.utils;

import java.security.Key;
import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;

/**
 * <p>
 * 鍥犱负浠绘剰涓?釜瀛楃涓诧紝閮芥槸鐢辫嫢骞插瓧鑺傝〃绀虹殑锛屾瘡涓瓧鑺傚疄璐ㄥ氨鏄竴涓湁8浣嶇殑杩涜繘鍒舵暟锛?
 * 鍙堝洜涓轰竴涓?浣嶄簩杩涘埗鏁帮紝鍙敤涓や綅16杩涘埗瀛楃涓茶〃绀恒?鍥犳浠绘剰涓?釜瀛楃涓插彲浠ョ敱涓や綅16杩涘埗瀛楃涓茶〃绀恒?
 * 鑰孌ES鏄8浣嶄簩杩涘埗鏁拌繘琛屽姞瀵嗭紝瑙ｅ瘑銆傛墍浠ョ敤DES鍔犲瘑瑙ｅ瘑鏃讹紝鍙互鎶婂姞瀵嗘墍寰楃殑8浣嶈繘杩涘埗鏁帮紝杞垚涓や綅16杩涘埗鏁拌繘琛屼繚瀛橈紝浼犺緭銆?br>
 * <br>
 * <b>鍙︼細涓?釜瀛楃涓插姞瀵嗗悗鎵?緱鐨?浣嶄簩杩涘埗鏁帮紝閫氬父涓嶅啀鏃跺瓧绗︿覆浜嗭紝濡傛灉 鐩存帴鎶婅繖绉嶅瘑鏂囨墍寰楃殑8浣嶄簩杩涘埗鏁板己鍒惰浆鎴愬瓧绗︿覆锛屾湁璁稿淇℃伅鍥犱负寮?
 * 甯歌?涓㈠け锛屽鍒惰В瀵嗗け璐ャ?鍥犲埗瑕佹妸杩欎釜8浣嶄簩鍒舵暟锛岀洿鎺ヤ互鏁扮殑褰㈠紡 淇濆瓨涓嬫潵锛岃?閫氬父鏄敤涓や綅鍗佸叚杩涘埗鏁拌〃绀恒?</b><br>
 * <br>
 * 鍏蜂綋鏂规硶锛?br>
 * 1. 鎶婁竴涓瓧绗︿覆杞垚8浣嶄簩杩涘埗鏁帮紝鐢―ES鍔犲瘑锛屽緱鍒?浣嶄簩杩涘埗鏁扮殑瀵嗘枃锛?br>
 * 2. 鐒跺悗鎶婏紙鐢?锛夋墍寰楃殑瀵嗘枃杞垚涓や綅鍗佸叚杩涘埗瀛楃涓诧紱<br>
 * 3. 瑙ｅ瘑鏃讹紝鎶婏紙鐢?锛夋墍寰楃殑涓や綅鍗佸叚杩涘埗瀛楃涓诧紝杞崲鎴?浣嶄簩杩涘埗 鏁扮殑瀵嗘枃锛?br>
 * 4. 鎶婏紙鐢?锛夋墍寰楃殑瀵嗘枃锛岀敤DES杩涜瑙ｅ瘑锛屽緱鍒?浣嶄簩杩涘埗鏁板舰寮忕殑鏄庢枃锛屽苟寮哄埗杞崲鎴愬瓧绗︿覆銆?br>
 * </p>
 */
public class DESEncrypt {

	private static final String T = "0";
	private static final String DES = "DES";
	private Key key;
	private Cipher cipherEnc;
	private Cipher cipherDec;

	public DESEncrypt(String key) throws Exception {
		cipherEnc = Cipher.getInstance(DES);
		cipherDec = Cipher.getInstance(DES);
		generateKey(key);
	}

	/**
	 * 鐢熸垚鍔犲瘑瀵嗛挜
	 * 
	 * @param key
	 */
	private void generateKey(String key) throws Exception {
		KeyGenerator generator = KeyGenerator.getInstance(DES);
		generator.init(new SecureRandom(key.getBytes()));
		// 鐢熸垚瀵嗛挜
		this.key = generator.generateKey();

		// 鍒濆鍖栧姞瀵嗚В瀵嗗伐鍏?
		cipherEnc.init(Cipher.ENCRYPT_MODE, this.key);
		cipherDec.init(Cipher.DECRYPT_MODE, this.key);

		generator = null;
	}

	/**
	 * 鍔犲瘑
	 * 
	 * @param src
	 *            婧愭暟鎹?
	 * @return 鍔犲瘑鍚庢暟鎹?
	 */
	public String encrypt(String src) throws Exception {
		return byte2hex(encrypt(src.getBytes()));
	}

	/**
	 * 瑙ｅ瘑
	 * 
	 * @param encryptedSrc
	 *            瀵嗘枃
	 * @return 鏄庢枃
	 */
	public String decrypt(String encryptedSrc) throws Exception {
		return new String(decrypt(hex2byte(encryptedSrc.getBytes())));
	}

	/**
	 * 鍔犲瘑浠yte[]鏄庢枃杈撳叆,byte[]瀵嗘枃杈撳嚭
	 * 
	 * @param bytes
	 * @return
	 */
	private byte[] encrypt(byte[] bytes) throws Exception {
		// Cipher cipher = Cipher.getInstance(DES);
		// cipher.init(Cipher.ENCRYPT_MODE, key);
		// return cipher.doFinal(bytes);
		return cipherEnc.doFinal(bytes);
	}

	/**
	 * 瑙ｅ瘑浠yte[]瀵嗘枃杈撳叆,浠yte[]鏄庢枃杈撳嚭
	 * 
	 * @param bytes
	 * @return
	 */
	private byte[] decrypt(byte[] bytes) throws Exception {
		// Cipher cipher = Cipher.getInstance(DES);
		// cipher.init(Cipher.DECRYPT_MODE, key);
		// return cipher.doFinal(bytes);
		return cipherDec.doFinal(bytes);
	}

	/**
	 * 浜岃鍒惰浆瀛楃涓?
	 * 
	 * @param b
	 * @return
	 */
	private static String byte2hex(byte[] b) { // 涓?釜瀛楄妭鐨勬暟锛?
		// 杞垚16杩涘埗瀛楃涓?
		String stmp = "";
		StringBuilder info = new StringBuilder();
		final int N = 0XFF;
		for (int n = 0; n < b.length; n++) {
			// 鏁存暟杞垚鍗佸叚杩涘埗琛ㄧず
			stmp = (Integer.toHexString(b[n] & N));
			if (stmp.length() == 1) {
				info.append(T).append(stmp);
			} else {
				info.append(stmp);
			}
		}
		return info.toString().toUpperCase();
	}

	private static byte[] hex2byte(byte[] b) {
		if ((b.length % 2) != 0)
			throw new IllegalArgumentException("Argument is not even.");
		byte[] b2 = new byte[b.length / 2];
		for (int n = 0; n < b.length; n += 2) {
			String item = new String(b, n, 2);
			// 涓や綅涓?粍锛岃〃绀轰竴涓瓧鑺?鎶婅繖鏍疯〃绀虹殑16杩涘埗瀛楃涓诧紝杩樺師鎴愪竴涓繘鍒跺瓧鑺?
			b2[n / 2] = (byte) Integer.parseInt(item, 16);
		}
		return b2;
	}

	public static void main(String[] args) {
		long a = System.currentTimeMillis();
		String src = "messageId=100&transactionType=4006&transMessage={'gamecode':'dlt','issue':'2011075'}&digest=D059AD055B22FF26753C153239D47819";
//		src = "杩欎笘涓婃渶闅句簡瑙ｇ殑鏄埍銆佺粰浜哄帇鍔涙渶澶х殑鏄埍銆侀?鎴愭渶澶氶棶棰樼殑鏄埍銆佸奖鍝嶆渶娣辩殑鏄埍銆傚嚒鏄埍寰楄繃澶氾紝澶氬埌鍙互鎶婂瀛愭汉姝荤殑锛岄兘鏄?婧虹埍銆嶃?鍏跺疄姣忕鍔ㄧ墿閮戒細鐖憋紝鐢氳嚦鍦ㄥ瀛愬皬鐨勬椂鍊欙紝閮戒細婧虹埍銆傛垜鍗у绐楀墠鏈夋５鐭虫鏍戯紝鍒颁簡鏄ュぉ锛屽父鏈夌煡鏇撮笩鍦ㄤ笂闈㈢瓚宸㈠铔嬶紝鎴戞?鐪嬭楦熺埜楦熷锛屽悇绔欏湪宸㈢殑涓?竟锛屽徏鐫?弧鍙ｇ殑灏忚櫕锛屼簤鐫?線楦熷▋濞冪殑鍢撮噷濉烇紝鍚冧笉涓嬩簡杩樼‖濉炪?濡欑殑鏄紝鐗犱滑濉炲綊濉烇紝鍙兘鏈変竴澶╋紝鍙堝甫鐫??澶ч奔澶ц倝銆嶅洖瀹讹紝鍗村彂鐜板瀛愬叏涓嶈浜嗐?杩欐椂鍊欏彧瑙佸ぇ楦熺珯鍦ㄥ发杈瑰彂鎰ｏ紝涓嶇煡鐗犲績閲屾槸浠?箞婊嬪懗銆傚皬楦熼浜嗭紝鍥犱负缈呰唨纭簡锛屼笉鍐嶉渶瑕佺埗姣嶆汉鐖便?";
		String key = "12580";

		try {
			DESEncrypt des = new DESEncrypt(key);

			System.out.println("src=\t" + src);
			String encSrc = des.encrypt(src);
			System.out.println("encSrc=" + encSrc);

			String decSrc = des.decrypt(encSrc);
			System.out.println("decSrc=\t" + decSrc);
			long b = System.currentTimeMillis() - a;
			System.out.println("time=" + b);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

